
#include "Tshm.h"

struct tshm_1byte_item tshm_1byte_item[]={
	{TSHM_CHAR1,"CHAR1",0},
	{TSHM_CHAR2,"CHAR2",0},
	{3939889,NULL,0}
};

TSHM_T *Tshmaddr=NULL;
int Tshm_sem_id;
union semun{
  int val;
  struct semid_ds *buf;
  unsigned short *array;
}Tshm_sem_union;

void Tshm_sem_init(int key){
	Tshm_sem_id = semget((key_t)key,1,0666 | IPC_CREAT);
	Tshm_sem_union.val=1;
	if (semctl(Tshm_sem_id,0,SETVAL,Tshm_sem_union)== -1)
    return;
}

int Tshm_sem_p(void){
	struct sembuf sem_b;
	sem_b.sem_num = 0;
  sem_b.sem_op = -1;
  sem_b.sem_flg = SEM_UNDO; //or IPC_NOWAIT, don't wait if unsuccessful
  if (semop(Tshm_sem_id,&sem_b,1) == -1)
		exit(EXIT_FAILURE);
  return 1;
}

int Tshm_sem_v(void){
	struct sembuf sem_b;
  sem_b.sem_num = 0;
  sem_b.sem_op = 1;
  sem_b.sem_flg = SEM_UNDO; //or IPC_NOWAIT, don't wait if unsuccessful
  if (semop(Tshm_sem_id,&sem_b,1) == -1)
		exit(EXIT_FAILURE);
  return 1;
}

void Tshm_init(void)
{
	int shmid;
	struct shmid_ds buf;
	int i;
	
	shmid = shmget(TSHM_KEY,TSHM_SIZE,IPC_CREAT|0666);
	Tshmaddr = (TSHM_T *)shmat(shmid,NULL,0);
	//printf("Tshm_init() at 0x%p,size %d,real struct size %d\n",Tshmaddr,size,sizeof(struct __data));
	Tshm_sem_init(TSHM_SEM_KEY);
	
	TSHM_T *p = (TSHM_T *)Tshmaddr;
	Tshm_sem_p();
	for(i=0;tshm_1byte_item[i].name!=NULL;i++){
		p->d.u1[i].id = tshm_1byte_item[i].id;
		p->d.u1[i].name = tshm_1byte_item[i].name;
	}
	Tshm_sem_v();
}

void Tshm_get(int id,void *value){
	TSHM_T *p = (TSHM_T *)Tshmaddr;
	*((U1 *)value) = p->d.u1[id].value;
}

void Tshm_set(int id,void *value){
	TSHM_T *p = (TSHM_T *)Tshmaddr;
	Tshm_sem_p();
	p->d.u1[id].value = *((U1 *)value);
	Tshm_sem_v();
}

void Tshm_default(void){
	TSHM_T *p = (TSHM_T *)Tshmaddr;
	int i;
	Tshm_sem_p();
	for(i=0;tshm_1byte_item[i].name!=NULL;i++){
		p->d.u1[i].value = 0;
	}
	Tshm_sem_v();
}

void Tshm_all_cmd(int argc, char **argv){
	TSHM_T *p = (TSHM_T *)Tshmaddr;
	int i;
	char *type = argv[1];
	char *name = argv[2];
	for(i=0;tshm_1byte_item[i].name!=NULL;i++){
		printf("%s=%d\n",p->d.u1[i].name,p->d.u1[i].value);
	}
}

void Tshm_get_cmd(int argc, char **argv){
	TSHM_T *p = (TSHM_T *)Tshmaddr;
	int i;
	char *type = argv[1];
	char *name = argv[2];
	for(i=0;tshm_1byte_item[i].name!=NULL;i++){
		if(!strcmp(name,p->d.u1[i].name)){
			printf("%s=%d\n",p->d.u1[i].name,p->d.u1[i].value);
		}
	}
}

void Tshm_set_cmd(int argc, char **argv){
	TSHM_T *p = (TSHM_T *)Tshmaddr;
	int i;
	char *type = argv[1];
	char *name = argv[2];
	U1 value = atoi(argv[3]);
	for(i=0;tshm_1byte_item[i].name!=NULL;i++){
		if(!strcmp(name,p->d.u1[i].name)){
			p->d.u1[i].value = value;
		}
	}
}
